package com.itheima.bakery.demos.web.config;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.Collections;
import org.springframework.stereotype.Component;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.AntPathMatcher;
@Component
public class JwtInterceptor implements Filter {
    private static final Logger logger = LoggerFactory.getLogger(JwtInterceptor.class);
    @Value("${jwt.secret}")
    private String secretKey;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        logger.info("Processing request: {}", httpRequest.getRequestURI());

        if (isJwtNeeded(httpRequest)) {
            String authHeader = httpRequest.getHeader("Authorization");
            String token = null;
            if (authHeader != null && authHeader.startsWith("Bearer ")) {
                token = authHeader.substring(7);
            } else if (httpRequest.getCookies() != null) {
                // 如果JWT存储在Cookie中，从Cookie获取
                for (Cookie cookie : httpRequest.getCookies()) {
                    if ("auth_token".equals(cookie.getName())) {
                        token = cookie.getValue();
                        break;
                    }
                }
            }

            if (token != null) {
                try {
                    Claims claims = Jwts.parser()
                            .setSigningKey(secretKey)
                            .parseClaimsJws(token)
                            .getBody();
                    String username = claims.getSubject();
                    Collection<? extends GrantedAuthority> authorities = getAuthoritiesFromClaims(claims);
                    Authentication authentication = new UsernamePasswordAuthenticationToken(username, null, authorities);
                    SecurityContextHolder.getContext().setAuthentication(authentication);

                    httpRequest.setAttribute("user", claims.getSubject());
                    httpRequest.setAttribute("roles", claims.get("role")); // 获取角色信息
                    logger.info("JWT parsed successfully for: {}", httpRequest.getRequestURI());
                    logger.info("User: {}", claims.getSubject());
                    logger.info("Roles: {}", claims.get("role"));
                    chain.doFilter(request, response);
                } catch (Exception e) {
                    logger.error("JWT validation error: {}", e.getMessage());
                    logger.error("JWT: {}", token);
                    httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                }
            } else {
                logger.error("No JWT provided for: {}", httpRequest.getRequestURI());
                httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            }
        } else {
            logger.info("Skipping JWT check for: {}", httpRequest.getRequestURI());
            chain.doFilter(request, response);
        }
    }

    /**
     * 从Claims中获取权限信息
     */
    private Collection<? extends GrantedAuthority> getAuthoritiesFromClaims(Claims claims) {

        String role = claims.get("role").toString();
        return Collections.singletonList(new SimpleGrantedAuthority(role));
    }

    /**
     * 检查请求是否需要JWT验证
     */
    private boolean isJwtNeeded(HttpServletRequest request) {
        String[] jwtNeededPaths = {"/adminview/**"};
        AntPathMatcher pathMatcher = new AntPathMatcher();
        for (String path : jwtNeededPaths) {
            if (pathMatcher.match(path, request.getRequestURI())) {
                logger.info("JWT needed for path: {}", request.getRequestURI());
                return true;
            }
        }
        logger.info("Skipping JWT check for path: {}", request.getRequestURI());
        return false;
    }
}